package com.hank.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hank.entity.LoginUser;
import com.hank.entity.User;
import com.hank.entity.dto.RegisterUser;
import com.hank.entity.vo.BlogUserLoginVo;
import com.hank.entity.vo.UserInfoVo;
import com.hank.mapper.UserMapper;
import com.hank.service.UserLoginService;
import com.hank.utils.BeanCopyUtils;
import com.hank.utils.JwtUtil;
import com.hank.utils.R;
import com.hank.utils.RedisCache;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.Objects;

/**
 *
 * 用户登录服务实现类
 *
 * @author hank
 * @since 2023-04-23
 */
@Slf4j
@Service
public class UserLoginServiceImpl implements UserLoginService {

    @Resource
    UserMapper userMapper;

    @Resource
    PasswordEncoder passwordEncoder;

    @Resource
    private AuthenticationManager authenticationManager;

    //唯一用户名校验
    @Override
    public R uniqueUsername(String username) {

        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("username",username);
        User user = userMapper.selectOne(wrapper);
        if (user == null) return R.ok();
        return R.error();
    }

    //登录
    @Override
    public R login(String username, String password) {

        UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(username,password);
        Authentication authenticate;
        try {
            authenticate = authenticationManager.authenticate(usernamePasswordAuthenticationToken);
        }catch (AuthenticationException e){
            return R.error("登陆失败！");
        }
        //获取用户详细信息
        LoginUser loginUser = (LoginUser) authenticate.getPrincipal();
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getUsername,username);
        User user = userMapper.selectOne(wrapper);

        //校验用户帐号状态
        if (user.getStatus()||user.getIsDeleted()){
            return R.error("登陆失败！");
        }

        //token生成
        UserInfoVo userInfoVo = BeanCopyUtils.copyBean(user, UserInfoVo.class);
        String jwt = JwtUtil.createJWT(user.getId().toString());

        //TODO 存入到Redis

        //返回数据给前端
        BlogUserLoginVo loginVo = new BlogUserLoginVo(jwt, userInfoVo);
        return R.ok().put("result",loginVo);
    }


    //登出
    @Override
    public R logout() {

        //获取token 解析获取userid
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        Integer id = loginUser.getUser().getId();

        log.info("---------------------------"+loginUser.toString());

        return R.ok();
    }

    //用户注册
    @Override
    public R userRegister(RegisterUser registerUser) {
        registerUser.setPassword(passwordEncoder.encode(registerUser.getPassword()));
        User user = new User();
        BeanUtils.copyProperties(registerUser,user);
        int insert = userMapper.insert(user);
        if (insert==1){
            return R.ok("注册成功！");
        }
        return R.error("注册失败！");
    }

}
